﻿using ChessTest.Chess.Items;
using System;
using System.Drawing;
using System.IO;
using org.xisoft.game.utils.game;
using ChessTest.Chess.Algorithms;
using org.xisoft.game.utils;
using System.Windows.Forms;
using System.Diagnostics;

namespace ChessTest.Chess
{
    /// <summary>
    /// 棋盘画板，把棋盘模型画出来，UI与逻辑分离
    /// </summary>
    public class ChessboardPanel : NormalBroadControl
    {
        private SortedAlphaBetaAlgorithm algorithm = new SortedAlphaBetaAlgorithm();
        public ChessboardPanel()
            :base(Chess.Chessboard.MAXX, Chess.Chessboard.MAXY)
        {


        }



        protected override void DrawChessBoardCol(Graphics g, int index, int left, int top, int height)
        {
            int midTop = height - GridItemHeight * 5;
            base.DrawChessBoardCol(g, index, left, top, midTop);
            base.DrawChessBoardCol(g, index, left, top+midTop+ GridItemHeight, height-midTop - GridItemHeight);
        }

        /// <summary>
        /// 画棋盘
        /// </summary>
        /// <param name="g"></param>
        /// <param name="rect"></param>
        protected override void DrawChessBoard(Graphics g, Rectangle rect)
        {
            base.DrawChessBoard(g, rect);

            //兵占
            for (int i = 0; i < 4; i++)
            {
                int y = 3 * GridItemHeight + rect.Top;
                int x = i * GridItemWidth * 2 + rect.Left;
                DrawCross(g, rect, x, y);
                y = rect.Bottom - 3 * GridItemHeight;
                DrawCross(g, rect, x, y);
            }

            //炮占
            DrawCross(g, rect, GridItemWidth + rect.Left, 2 * GridItemHeight + rect.Top);
            DrawCross(g, rect, rect.Right - GridItemWidth, 2 * GridItemHeight + rect.Top);
            DrawCross(g, rect, GridItemWidth + rect.Left, 7 * GridItemHeight + rect.Top);
            DrawCross(g, rect, rect.Right - GridItemWidth, 7 * GridItemHeight + rect.Top);


            //皇宫格
            g.DrawLine(broadPen, GridItemWidth * 3 + rect.Left, rect.Top, GridItemWidth * 5 + rect.Left, 2 * GridItemHeight + rect.Top);
            g.DrawLine(broadPen, GridItemWidth * 3 + rect.Left, rect.Top + 2 * GridItemHeight, GridItemWidth * 5 + rect.Left, rect.Top);
            g.DrawLine(broadPen, GridItemWidth * 3 + rect.Left, rect.Bottom, GridItemWidth * 5 + rect.Left, rect.Bottom - 2 * GridItemHeight);
            g.DrawLine(broadPen, GridItemWidth * 3 + rect.Left, rect.Bottom - 2 * GridItemHeight, GridItemWidth * 5 + rect.Left, rect.Bottom);
        }

        private void DrawCross(Graphics g, Rectangle rect, int x, int y)
        {
            int l = x - 2;

            if (l < rect.Left)
                l += rect.Width;
            g.DrawLines(broadPen, new Point[] { new Point(l - 2, y - 2), new Point(l, y - 2), new Point(l, y - 4) });
            g.DrawLines(broadPen, new Point[] { new Point(l - 2, y + 2), new Point(l, y + 2), new Point(l, y + 4) });
            g.DrawLines(broadPen, new Point[] { new Point(x + 2, y + 4), new Point(x + 2, y + 2), new Point(x + 4, y + 2) });
            g.DrawLines(broadPen, new Point[] { new Point(x + 2, y - 4), new Point(x + 2, y - 2), new Point(x + 4, y - 2) });
        }

        protected override void DrawItems(Graphics g,Rectangle rect)
        {
            if (selectedChessman != null)
            {
                int x = selectedChessman.PositionX * GridItemWidth - ItemWidth / 2 + rect.Left;
                int y = selectedChessman.PositionY * GridItemHeight - ItemHeight / 2 + rect.Top;

                g.FillRectangle(Brushes.Red, x-1, y-1, ItemWidth+2, ItemHeight+2);
                g.DrawEllipse(selectedItemPen, new Rectangle(x-1, y-1, ItemWidth+2, ItemHeight+2));
            }


            SolidBrush backBrush = new SolidBrush(Color.FromArgb(0xef, 255, 250, 240));
            for (int i = 0; i < MaxX; i++)
            {
                for (int j = 0; j < MaxY; j++)
                {
                    Chessman chessman = Chessboard.GetChessman(i, j);
                    if (chessman != null)
                    {

                        SizeF size = g.MeasureString(chessman.DisplayName, Font);
                        Brush brush = chessman.IsBlack ? blackItemBrush : writeItemBrush;
                        Pen p = chessman.IsBlack ? blackItemPen: writeItemPen ;
                        int x = chessman.PositionX * GridItemWidth - ItemWidth / 2 + rect.Left;
                        int y = chessman.PositionY * GridItemHeight - ItemHeight / 2 + rect.Top;
                        g.FillEllipse(backBrush, new Rectangle(x, y, ItemWidth, ItemHeight));

                        g.DrawString(chessman.DisplayName, Font, brush, x + (ItemWidth - size.Width + 2f) / 2, y + (ItemHeight - size.Height + 2f) / 2);
                        g.DrawEllipse(p, new Rectangle(x, y, ItemWidth, ItemHeight));
                    }
                }
            }


        }

        private Chessman selectedChessman;
        protected override void OnClick(int selectX, int selectY)
        {

            if (selectX < 0 || selectX >= MaxX)
                return;
            if (selectY < 0 || selectY >= MaxY)
                return;

            Chessman chessman = Chessboard.GetChessman(selectX, selectY);
            if (selectedChessman == null && chessman != null)
            {
                if (Chessboard.IsCurrentBlackMove == chessman.IsBlack)
                    selectedChessman = chessman;
            }
            else if (selectedChessman != null)
            {
                if (!selectedChessman.CanMove(Chessboard, selectX, selectY))
                {
                    selectedChessman = null;
                    Invalidate();
                    return;
                }
                MoveAction moveAction = new MoveAction { CurrentChessman = selectedChessman, ToX = selectX, ToY = selectY };

                Chessboard.DoNextMove(moveAction);
                Invalidate();
                selectedChessman = null;

                AiChessboard newBoard = Chessboard.Clone() as AiChessboard;



                AsyncTask<AiChessboard, MoveAction> task = new AsyncTask<AiChessboard, MoveAction>(ChessBoardControl, DoAfterMove);
                task.Start(algorithm.Search, newBoard);
            }
        }

        private void DoAfterMove(MoveAction action)
        {


            if (action == null || action.CurrentChessman == null)
            {
                MessageBox.Show("你赢了");
                return;
            }



            Chessman current = Chessboard[action.FromX, action.FromY] as Chessman;
            action.CurrentChessman = current;
            
            Chessboard.DoNextMove(action);
            Invalidate();

            if (action.Score > 1000)
            {
                Debug.WriteLine("lose");
                MessageBox.Show("你被包围了，放弃吧");
 
            }

        }

        public override void Read(BinaryReader br)
        {
            Chessboard.Read(br);
        }

        public override void Save(BinaryWriter bw)
        {
            Chessboard.Save(bw);
        }



        public override void Undo()
        {
            Chessboard.Undo();
            Chessboard.Undo();
        }

        private AiChessboard chessboard = new AiChessboard();
        protected  AiChessboard Chessboard { get { return chessboard; } }

        public override string Name => "中国象棋"; 
    }
}
